package com.cskaoyan.javase.array._7callby;

import java.util.Arrays;

/**
 * 方法的传值问题:
 * 什么是方法的传参问题: 方法在调用时,是需要传给方法一个实参变量的,那么在方法体去修改这个实参的取值,方法结束后,实参的取值会发生什么变化?
 *
 * 方法的传值有两种形式:
 * 1.值传递: 方法得到的不是实参本身,而是实参的拷贝.
 *      如果是值传递,那么方法不能改变实参变量的取值
 *
 * 2.引用传递: 方法得到的是实参的地址(就是实参本身)
 *      如果是引用传递,那么方法可以修改实参变量的取值
 *
 *
 *
 * 我们通过对基本数据类型实参的测试,发现:
 *      至少对于基本数据类型,方法不能修改它的取值,Java是值传递的
 * 我们通过对引用数据类型实参的测试(数组),发现:
 *      至少对于引用数据类型,方法可以修改它的取值,Java是引用传递的
 *
 * 以上结论是完全错误的,是典型的互联网低水平博主的言论,
 * 是不经思考得出的结论,是错误的.是完全没有理解Java引用数据类型本质的
 *
 * 注意真正的结论是:  Java当中只有值传递,没有任何引用传递
 * 接下来我们通过画图论证它.
 *
 * 结论:
 *      1.java的方法是不能修改任何局部变量的取值的(包括基本数据类型变量和引用数据类型的引用)
 *          因为局部变量是不可能在方法外部生效的
 *      2.Java的方法可以修改对象中元素的取值,因为拷贝的引用和原先的实参引用指向的是同一个对象
 *          在java中,把修改对象中元素的取值,称之为修改"对象的状态"
 *          如果元素取值不变,就称之为对象的状态不变.
 *
 * @since 15:42
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 测试
        int a = 10;
        doubleIntValue(a);
        System.out.println(a);
        System.out.println("----------------");

        int[] arr = {1, 2, 3};
        doubleArrElement(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------");

        int[] arr1 = {666, 777, 888};
        int[] arr2 = {6, 7, 8};
        System.out.println("交换之前arr1:"+Arrays.toString(arr1));
        System.out.println(arr1);
        System.out.println("交换之前arr2:"+Arrays.toString(arr2));
        System.out.println(arr2);
        /*
            交换如果成功,表示java是有引用传递的
            交换失败,表示java是值传递
            结果是交换失败
            Java只有值传递
         */
        swapArrReference(arr1, arr2);
        System.out.println("交换之后arr1:"+Arrays.toString(arr1));
        System.out.println(arr1);
        System.out.println("交换之后arr2:"+Arrays.toString(arr2));
        System.out.println(arr2);
    }

    /*
        Java中的变量分为两种:
            1.基本数据类型
            2.引用数据类型
        分别测试不同数据类型实参传入方法后,是否能够改变它的取值
     */

    // 将一个int数值,通过方法变成它的2倍
    public static void doubleIntValue(int a) {
        a *= 2;
    }

    // 将数组中的元素扩大为原先的2倍
    public static void doubleArrElement(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }

    // 交换两个数组的引用
    public static void swapArrReference(int[] arr1, int[] arr2) {
        // 交换元素,闭着眼睛写temp
        int[] temp = arr1;
        arr1 = arr2;
        arr2 = temp;
        System.out.println("------------------------------------");
        System.out.println("交换之中方法内部arr1:"+Arrays.toString(arr1));
        System.out.println(arr1);
        System.out.println("交换之中方法内部arr2:"+Arrays.toString(arr2));
        System.out.println(arr2);
        System.out.println("------------------------------------");
    }
}
